<?php
/**
 * 考勤明细
 */
apf_require_controller('Oa_Attendance_Abstract');
apf_require_class('Tools_Tools');
class Oa_Attendance_AttendanceController extends Oa_Attendance_AbstractController {
const PAGEROW = 10;
    const MONTHWORKDAILY = 28;//当月工作结算日
    public function handle_request() {

        $Tools = Tools_Tools::get_instance();#1
        $params = $this->request->get_parameters();

        //获得需要显示的年、月
        $default_year = $this->get_default_year($params['select_year']);
        $params['select_year'] = $default_year;
        $default_month = $this->get_default_month($params['select_month']);
        $params['select_month'] = $default_month;
        $default_month_display = $params['select_year'].$params['select_month'].'01';
        $this->request->set_attribute('display_month',date('m月',strtotime($default_month_display)));

        $base_domain = APF::get_instance()->get_config('base_domain');
        $this->request->set_attribute('base_domain',$base_domain.'/attendance/');

        //显示时间
        $curr_time = $this->get_curr_time();
        $this->request->set_attribute('curr_time',$curr_time);

        $params['p'] = empty($params['p']) ? 1 : intval($params['p']);
        //查询用户
        $userlist_tmp = $this->search_users($params);
        $userlist = $userlist_tmp['data'];
      //  print_r($userlist_tmp);
        if ($userlist_tmp['next_p']) { // 没有下一页则链接到尾页
            $params['next_page'] = $params['p'] + 1;
        } else {
            $params['next_page'] = $params['p'];
        }
        if ($params['p'] > 1) {
            $params['pre_page'] = $params['p'] - 1;
        } else { // 没有上一页则链接到首页
            $params['pre_page'] = 1;
        }
        $this->request->set_attribute('userlist',$userlist);
        $this->request->set_attribute('user_id',$_SESSION['user_id']);
        $this->request->set_attribute('params',$params);
        return 'Oa_Attendance_Attendance';
    }

    public function get_curr_time() {
        if(date('H') > 0 && date('H') < 12) {
            $ma = '上午';
        } else {
            $ma = '下午';
        }
        return date('Y').'年'.date('m').'月'.date('d')."日&nbsp;&nbsp;&nbsp;星期".Tools_Tools::get_instance()->convert_chinese_week(date('w'))."&nbsp;&nbsp;&nbsp;&nbsp;".$ma."&nbsp;&nbsp;&nbsp;".date('h:i');
    }

    /**
     * 获得本月结束日
     */
    public function get_month_word_end_day($yearmonth = 0) {
        $Tools = Tools_Tools::get_instance();
        if(empty($yearmonth)) {
            $yearmonth = date('Ym');
        }
        $workendday = $yearmonth.self::MONTHWORKDAILY;
        //查找数据库里是否有当月的结算时间
        $bll_monthset = $this->init_month_set();
        $month_set = $bll_monthset->get_month_special_set($yearmonth);
        if(!empty($month_set['settlement'])) {
            $workendday = substr($month_set['settlement'],0,10);
        }
        return $workendday;
    }

    /**
     * 一个月的实际工作日
     * 1.优先从表中查询是否有设置月份的结束工作日。
     * @param unknown_type $workendday
     */
    public function get_month_work_day($yearmonth = 0) {
        $Tools = Tools_Tools::get_instance();
        $workday = 0;
        if(empty($yearmonth)) {
            $yearmonth = date('Ym');
        }
        $yearmonthday = $yearmonth.self::MONTHWORKDAILY;
        //查找数据库里是否有当月的结算时间
        $bll_monthset = $this->init_month_set();
        $month_set = $bll_monthset->get_month_special_set($yearmonth);
        if(empty($month_set)) {
            $time = strtotime($yearmonthday);
            $workday = $Tools->dissmion_work_day_by_month($time);
        }else {
            $workday = $month_set['work_day'];
            if(empty($workday) && !empty($month_set['settlement'])) {
                $time = substr($month_set['settlement'],0,10);
                $time = strtotime($time);
                $workday = $Tools->dissmion_work_day_by_month($time);
            }else if(empty($workday)) {
                $time = strtotime($yearmonthday);
                $workday = $Tools->dissmion_work_day_by_month($time);
            }
        }
        return $workday+1;
    }

    /**
     * 得到年份
     */
    public function get_default_year($year) {
        $year = (int)$year;
        if(empty($year)) {
            $year = date('Y');
        }
        return $year;
    }

    /**
     * 得到月份
     */
    public function get_default_month($month) {
        if(empty($month)) {
            $month = date('m');
        }
        return $month;
    }

      /**
       * 搜索用户
       * @param unknown_type $params
       * @param int $work_att_day 每月应工作多少天
       */
    public function search_users($params) {
        $Tools = Tools_Tools::get_instance();

        //apf_require_controller('Oa_Attendance_UserDetail');
        //$userdetail_controller = new Oa_Attendance_UserDetailController();
        $result = array();
        $bll_userinfo = $this->init_userinfo();
        $result = $bll_userinfo->get_user_by_ids($this->uinfo['user_id']);
        //$result = $bll_userinfo->get_user_by_ids(2);
        $time = time();
        $data = array();

        $offset_month = 0;
        $offset_year = 0;
        # 每页显示10条记录（按月）
        $base = 10;

        if ($params['p'] >= 1) { // 分页机制
            $offset = ($params['p'] - 1) * $base;
            if ($offset < 12) { // 一年之内的记录
                $offset_month = $offset;
            } else { // 往年查询
                $offset_month = $offset % 12;
                $offset_year = ($offset - $offset_month) / 12;
            }
        }

        //需要计算的月份,每次传一次月
        apf_require_class("Bll_Attendance_Report");
        $report_bll= new Bll_Attendance_Report();
        $page = (int)$params['p'];
        $page = empty($page) ? 1:$page;
        $params['offset'] = ($page-1)*self::PAGEROW;
        $params['row'] = self::PAGEROW;
        $params['user_id'] = $this->uinfo['user_id'];

        $data = $report_bll->build_report_detail_data($params);

        $next_p = true;
        // 取n+1条记录，如果拿到了n+1条，证明有下一页，因为每页只显示n条记录;
        // 反之，则没有下一页。
        // 分页机制比较烂。
        /*if (count($data) > $base) { // 有下一页
            unset($data[$ym]);
            $next_p = true;
        } else { // 没有下一页
            $next_p = false;
        }*/
        return array('data'=>$data,'next_p'=>$next_p);


        for($i = 0;$i<=$base;$i++) {

            $month = date('m',$time);
            $start = date('Y-m-d',mktime(0,0,0,$month-$i-$offset_month,1,date('Y',$time)-$offset_year));//本月开始
            $end = date('Y-m-d',mktime(0,0,0,$month-($i-1)-$offset_month,1,date('Y',$time))-86400-$offset_year);
            $ym = date('Y年m月',strtotime($start));

            $default_year = date('Y',strtotime($start));
            $default_month = date('m',strtotime($start));
            //每月应工作的天数

            $work_att_day = $Tools->current_month_work_day($default_year,$default_month);
            $this->request->set_attribute('work_att_day',$work_att_day);

            //组装用户的考勤信息
            if(!empty($result)) {
                $user_ids = array();
                foreach($result as $v) {
                    $user_ids[] = $v['user_id'];
                }

                //用户的考勤记录
                $record_info = $bll_userinfo->get_users_record(array($this->uinfo['user_id']),$start,$end);

                //员工应扣餐补天数
                $leave_info_all = $this->memger_leavetime($record_info['leave_info_all']);

                //获得用户的上月未扣数据<只获取用户的请假信息>
                $prex_record_info = $this->get_prex_record_info($user_ids,$default_year."-".$default_month);
                //用户请假信息
                $leave_info = $this->memger_leavetime($record_info['leave_info']);
                //用户迟到信息
                $belate_info = $this->memger_belateinfo($record_info['belate_info']);
                //用户公出信息
                $corptrip_info = $this->memger_corptripinfo($record_info['corptrip_info']);
                //用户出差信息
                $trip_info = $this->memger_tripinfo($record_info['trip_info']);
                //用户事假信息
                $sj_info = $this->memger_sjinfo($record_info['sj_info']);
                //用户病假信息
                $bj_info = $this->memger_bjinfo($record_info['bj_info']);
                //用户年假信息
                $nj_info = $this->memger_njinfo($record_info['nj_info']);
                //用户其他假信息
                $oj_info = $this->memger_ojinfo($record_info['oj_info']);

                $Ym = date('Ym');

                $_Ym = $params['select_year'].$params['select_month'];

                //组装
                foreach($result as $key=>$v) {
                    //实际工作天数
                    $work_act_day = 0;
                    if($_Ym<=$Ym) {
                        $work_act_day = $work_att_day;
                        $work_meal_day = $work_att_day;
                    }

                    $oa_cd = 0;//迟到
                    $oa_gc = $oa_all_gc = 0;//公出
                    $oa_cc = 0;//出差
                    $oa_sj = $oa_all_sj = 0;//事假
                    $oa_bj = $oa_all_bj = 0;//病假
                    $oa_nj = $oa_all_nj = 0;//年假
                    $oa_oj = $oa_all_oj = 0;//其他假
                    $oa_prexj = 0;//上月未扣

                    $oa_kg = 0;//旷工天数

                    //start----------特殊处理
                    apf_require_class('Tools_Tools');
                    $Tools = Tools_Tools::get_instance();
                    $start_year = $default_year;
                    $start_month = $default_month;
                    //当月入职工作天数统计
                    $entertime = strtotime($v['enter_date']);
                    $firstday = mktime(0,0,0,$start_month,1,$start_year);
                    $Dimission = strtotime($v['dimission_date']);
                    $flag_dis_enter = false;
                    $flag_dismiss = false;
                    $flag_enter = false;

                    //当月入职工作天数统计
                    if($entertime > $firstday) {
                        if(date('Y-m',$entertime) == date('Y-m',mktime(0,0,0,$start_month,1,$start_year))) {
                            $work_act_enter_day =  $Tools->dissmion_work_day_by_month($entertime);//本月月初有多少天没上班
                        } else {
                            $work_act_enter_day = 0;
                        }
                        $flag_enter = true;
                    }
                    //当月离职工作天数统计
                    if($v['dimission_date'] != '0000-00-00 00:00:00') {
                        if(date('Ym',$Dimission) == date('Ym',mktime(0,0,0,$start_month,1,$start_year))) {
                            //当前月离职
                            $work_act_day_dismiss = $Tools->dissmion_work_day_by_month($Dimission)+1;
                        } elseif(date('Ym',$Dimission) < date('Ym',mktime(0,0,0,$start_month,1,$start_year))) {
                            //离职小于当前时间
                            $work_act_day_dismiss = 0;
                        }
                        $flag_dismiss = true;
                    }
                    //当月入职,当月离职
                    if (date('Ym',$Dimission) == date('Ym',$entertime)) {
                        $work_act_day_dismiss = $Tools->dissmion_work_day_by_month($Dimission) - $Tools->dissmion_work_day_by_month($entertime)+1;
                        $flag_dis_enter = true;
                    }
                    //----------------end

                    //领餐补天数
                    if(isset($leave_info_all[$v['user_id']]) or $flag_dis_enter or $flag_dismiss or $flag_enter) {
                        $work_meal_day = $work_att_day-$leave_info_all[$v['user_id']]['leave_time'];
                        //本月离职的
                        if($flag_dismiss or $flag_dis_enter){
                            $work_meal_day = $work_act_day_dismiss-$leave_info_all[$v['user_id']]['leave_time'];
                        }
                        //本月入职
                        elseif($flag_enter){
                            $work_meal_day = $work_meal_day - $work_act_enter_day;
                        }
                    }
                    //领工资天数
                    if(isset($leave_info[$v['user_id']]) or $flag_dis_enter or $flag_dismiss or $flag_enter) {
                        $work_act_day = $work_att_day-$leave_info[$v['user_id']]['leave_time'];
                        //本月离职的
                        if($flag_dismiss or $flag_dis_enter){
                            $work_act_day = $work_act_day_dismiss-$leave_info[$v['user_id']]['leave_time'];
                        }
                        //本月入职
                        elseif($flag_enter){
                            $work_act_day = $work_act_day - $work_act_enter_day;
                        }
                    }
                    if(isset($belate_info[$v['user_id']])) {
                        $oa_cd = $belate_info[$v['user_id']]['oa_cd'];
                    }
                    if(isset($corptrip_info[$v['user_id']])) {//公出
                        $oa_gc = $corptrip_info[$v['user_id']]['leave_time'];
                        $oa_all_gc = $corptrip_info[$v['user_id']]['leave_all_time'];
                    }
                    if(isset($trip_info[$v['user_id']])) {
                        $oa_cc = $trip_info[$v['user_id']]['leave_time'];
                    }
                    if(isset($sj_info[$v['user_id']])) {
                        $oa_sj = $sj_info[$v['user_id']]['leave_time'];
                        $oa_all_sj = $sj_info[$v['user_id']]['leave_all_time'];//所有事假申请
                    }
                    if(isset($bj_info[$v['user_id']])) {
                        $oa_bj = $bj_info[$v['user_id']]['leave_time'];
                        $oa_all_bj = $bj_info[$v['user_id']]['leave_all_time'];//所有病假申请
                    }
                    if(isset($nj_info[$v['user_id']])) {
                        $oa_nj = $nj_info[$v['user_id']]['leave_time'];
                        $oa_all_nj = $nj_info[$v['user_id']]['leave_all_time'];//所有年假申请
                    }
                    if(isset($oj_info[$v['user_id']])) {
                        $oa_oj = $oj_info[$v['user_id']]['leave_time'];
                        $oa_all_oj = $oj_info[$v['user_id']]['leave_all_time'];
                    }
                    if(isset($prex_record_info[$v['user_id']])) {
                        $oa_prexj = $prex_record_info[$v['user_id']]['leave_time'];
                    }

                    //迟到旷工
                    $my = array('uid'=>$v['user_id'],'ym'=>$default_year.$default_month);
                    $cd_kg = $bll_userinfo->get_cd_kg($my);
                    $oa_cd = $cd_kg['cd']?$cd_kg['cd']:0;
                    $oa_kg = $cd_kg['kg']?$cd_kg['kg']:0;

                    $result[$key]['work_act_day'] = $work_act_day;
                    $result[$key]['rice_day'] = floor($work_meal_day);
                    //餐费信息
                    $result[$key]['meal'] = $this->get_meal($work_att_day,$work_meal_day);
                    $result[$key]['oa_cd'] = $oa_cd;
                    $result[$key]['oa_gc'] = $oa_gc;
                    $result[$key]['oa_all_gc'] = abs($oa_all_gc);
                    $result[$key]['oa_cc'] = $oa_cc;
                    $result[$key]['oa_sj'] = $oa_sj;
                    $result[$key]['oa_all_sj'] = $oa_all_sj;
                    $result[$key]['oa_bj'] = $oa_bj;
                    $result[$key]['oa_all_bj'] = $oa_all_bj;
                    $result[$key]['oa_nj'] = $oa_nj;
                    $result[$key]['oa_all_nj'] = $oa_all_nj;
                    $result[$key]['oa_oj'] = $oa_oj;
                    $result[$key]['oa_all_oj'] = $oa_all_oj;
                    $result[$key]['oa_kg'] = $oa_kg;//旷工
                    $result[$key]['oa_prexj'] = $oa_prexj;
                    $result[$key]['oa_url'] = $userdetail_controller->build_url($v['user_id'],$default_year.$default_month);
                    $result[$key]['work_att_day'] = $work_att_day;
                    $data[$ym] = $result;
                }
            }
        }
        $next_p = true;
        // 取n+1条记录，如果拿到了n+1条，证明有下一页，因为每页只显示n条记录;
        // 反之，则没有下一页。
        // 分页机制比较烂。
        if (count($data) > $base) { // 有下一页
            unset($data[$ym]);
            $next_p = true;
        } else { // 没有下一页
            $next_p = false;
        }
        return array('data'=>$data,'next_p'=>$next_p);
    }

    /**
     * 获得上月未扣的假
     * @param unknown_type $uids
     * @param unknown_type $endtime
     */
    public function get_prex_record_info($uids,$endtime = 0) {
        $time = strtotime($endtime);
        $month = date('m',$time);
        //1.得到上月的结算时间
        $start = date('Ym',mktime(0,0,0,$month-1,1,date('Y-m-d',$time)));
        $start = $this->get_month_word_end_day($start);
        $time = strtotime($start)+86400;
        $start = date('Y-m-d',$time);
        $end = date('Y-m-d',mktime(0,0,0,$month,1,date('Y',$time))-86400)." 23";

        $bll_userinfo = $this->init_userinfo($uids,$start,$end);
        $result = $bll_userinfo->get_users_record($uids,$start,$end);
        return $this->memger_leavetime($result['leave_info']);
    }

    /**
     * 餐补计算
     * @param unknown_type $att_day 应出勤天数
     * @param unknown_type $act_day 实出勤天数
     */
    public function get_meal($att_day,$act_day) {
        $meal = APF::get_instance()->get_config('oa_meal');
        $meal = round($meal/$att_day*$act_day);
        return $meal;
    }

    /**
     * 时间格式处理
     */
    public function get_time($time = 0) {
        $result = array('start'=>0,'end'=>'0');
        if(empty($time)) {
            return $result;
        }
        //echo $time;
        $time = strtotime($time);
        $month = date('m',$time);
        $start = date('Y-m-d',mktime(0,0,0,$month,1,date('Y',$time)));//本月开始
        $end = date('Y-m-d',mktime(0,0,0,$month+1,1,date('Y',$time)));//结束日期
        $end = $this->get_month_word_end_day(date('Ym',$time));
        $result['start'] = $start;
        $result['end'] = $end;
        return $result;
    }

    /**
     * 获取当前用户下属的部门信息
     */
    public function get_department_info($level) {
        //得到当前用户的下属列表,1级下属
        $user_id = $this->uinfo['user_id'];
        $bll_role = new Bll_Attendance_Role();
        if(empty($level)) {$level=1;}else if($level=='all') {$level=0;}
        $subordinate_users = $bll_role->get_subordinate_by_user(1,$level);
        if(empty($subordinate_users)) {
            return array();
        }

        $user_ids = array();
        foreach($subordinate_users as $v) {
            $user_ids[] = $v['user_id'];
        }

        //得到用户部门信息
        $bll_user = new Bll_Login_User();
        $user_info = $bll_user->get_user_info_by_ids($user_ids);
        //$department_info = array();
        $city_info = array();
        $citydepartment = array();//城市与部门的对应关系
        $data = array();
        if(!empty($user_info)) {
            foreach($user_info as $v) {
                $tmp = array();
                $tmp['department_id'] = $v['department_id'];
                $tmp['department_name'] = $v['department_name'];

                //$department_info[$v['department_id']] = $v['department_name'];
                $city_info[] = $v['city_name'];
                $citydepartment[$v['city_name']][$v['department_id']] = $tmp;
            }
            if(!empty($citydepartment)) {
                foreach($citydepartment as $cityname => $v) {
                    ksort($v);
                    $v = array_values($v);
                    $citydepartment[$cityname] = $v;
                }
            }
        }
        $city_info = array_unique($city_info);
        //$data['department'] = $department_info;
        $data['cityname'] = $city_info;
        $data['citydepartment'] = json_encode($citydepartment);
        return $data;
    }

    /**
     * 获取翻页
     * @param unknown_type $totalnum 总的页数
     * @param unknown_type $page_num 当前第几页
     * @param array $url_params
     * @param int $uid 用户ID
     */
    public function build_multiPage_info($totalnum,$page_num = 0,$url_params = array()) {
        apf_require_class('Tools_MultiPage');
        //翻页信息
        $url = "/report/";
        $total_rows = $totalnum;
        if($page_num <= 0){$page_num = 1;}
        $url_params['p'] = $page_num;

        $multipage = Tools_MultiPage::multiPage($url,$url_params, '', $total_rows, self::PAGEROW, 10);
        return $multipage;
    }

    /**
     * 组合用户其他假信息
     */
    public function memger_ojinfo($rs) {
        $result = $this->memger_leavetime($rs);
        return $result;
    }

    /**
     * 组合用户年假信息
     */
    public function memger_njinfo($rs) {
        $result = $this->memger_leavetime($rs);
        return $result;
    }

    /**
     * 组合用户病假信息
     */
    public function memger_bjinfo($rs) {
        $result = $this->memger_leavetime($rs);
        return $result;
    }

    /**
     * 组合用户事假信息
     * @param unknown_type $rs
     */
    public function memger_sjinfo($rs) {
        $result = $this->memger_leavetime($rs,1);
        return $result;
    }

    /**
     * 组合用户出差信息
     * @param unknown_type $rs
     * @return multitype:|Ambigous <multitype:, unknown>
     */
    public function memger_tripinfo($rs) {
        $result = $this->memger_leavetime($rs);
        return $result;
    }

    /**
     * 组合用户公出信息
     * @param unknown_type $rs
     * @return array(userid=>公出天数)
     */
    public function memger_corptripinfo($rs) {
        $result = $this->memger_leavetime($rs);
        return $result;
    }

    /**
     * 组合用户迟到信息
     * @param unknown_type $rs
     * @return array(userid=>迟到次数)
     */
    public function memger_belateinfo($rs) {
        $result = array();
        if(empty($rs)) {return array();}
        foreach($rs as $key=>$v) {
            if(isset($result[$v['user_id']])) {
                $result[$v['user_id']]['oa_cd'] += 1;
            }else {
                $result[$v['user_id']]['oa_cd'] = 1;
            }
        }
        return $result;
    }

    /**
     * 组合用户请假信息
     * @param unknown_type $rs
     * @return array(userid=>请假天数)
     */
    public function memger_leavetime($rs,$st=0) {
        $result = array();
        if(empty($rs)) {return array();}
        foreach($rs as $v) {
            if(isset($result[$v['user_id']])) {
                if($v['leave_status']){
                    $result[$v['user_id']]['leave_time'] += $v['leave_time'];
                }
                $result[$v['user_id']]['leave_all_time'] += $v['leave_time'];
            }else {
                $result[$v['user_id']]['leave_time'] = $v['leave_status'] ? $v['leave_time'] : 0 ;
                $result[$v['user_id']]['leave_all_time'] = empty($v['leave_time']) ? 0 : $v['leave_time'];
            }
        }
        return $result;
    }
}
